use ClientPlatform
var criteriaToAdd = 
{ Name: "Stakeholder Governance Indicators", Level3: [
    { Name: "CG.6.12 Whistleblower Programmes", Level4: [{ Name: "CG.6.12 Whistleblower Programmes-Score", CriteriaEntityField: "CG612 Whistleblower Programmes-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.13 Tax Disclosure", Level4: [{ Name: "CG.6.13 Tax Disclosure-Score", CriteriaEntityField: "CG613 Tax Disclosure-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.14 Discrimination Policy", Level4: [{ Name: "CG.6.14 Discrimination Policy-Score", CriteriaEntityField: "CG614 Discrimination Policy-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.15 Scope of Social Supplier Standards", Level4: [{ Name: "CG.6.15 Scope of Social Supplier Standards-Score", CriteriaEntityField: "CG615 Scope of Social Supplier Standards-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.16 CDP Participation", Level4: [{ Name: "CG.6.16 CDP Participation-Score", CriteriaEntityField: "CG616 CDP Participation-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.17 GHG Reduction Programme", Level4: [{ Name: "CG.6.17 GHG Reduction Programme-Score", CriteriaEntityField: "CG617 GHG Reduction Programme-Score", IsScreenable: true, CriteriaType: 17 }] },
    { Name: "CG.6.18 Green Procurement Policy", Level4: [{ Name: "CG.6.18 Green Procurement Policy-Score", CriteriaEntityField: "CG618 Green Procurement Policy-Score", IsScreenable: true, CriteriaType: 17 }] },
]};

var criteriaToDelete = 
{ 
    Name: "Stakeholder Governance Indicators", Level3: [ 
        { Name: "CG.6.11 Tax Avoidance Incidents", Level4: [{ Name: "CG.6.11 Tax Avoidance Incidents-Score", CriteriaEntityField: "CG611 Tax Avoidance Incidents-Score" }] },
        { Name: "CG.6.9 Public Policy Incidents", Level4: [{ Name: "CG.6.9 Public Policy Incidents-Score", CriteriaEntityField: "CG69 Public Policy Incidents-Score" }] }
]};


function uuid() {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
}

function HexToBase64(hex) {
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var base64 = "";
    var group;
    for (var i = 0; i < 30; i += 6) {
        group = parseInt(hex.substr(i, 6), 16);
        base64 += base64Digits[(group >> 18) & 0x3f];
        base64 += base64Digits[(group >> 12) & 0x3f];
        base64 += base64Digits[(group >> 6) & 0x3f];
        base64 += base64Digits[group & 0x3f];
    }
    group = parseInt(hex.substr(30, 2), 16);
    base64 += base64Digits[(group >> 2) & 0x3f];
    base64 += base64Digits[(group << 4) & 0x3f];
    base64 += "==";
    return base64;
}

function NUUID(uuid) {
    var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
    var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
    var b = hex.substr(10, 2) + hex.substr(8, 2);
    var c = hex.substr(14, 2) + hex.substr(12, 2);
    var d = hex.substr(16, 16);
    hex = a + b + c + d;
    var base64 = HexToBase64(hex);
    return new BinData(3, base64);
}

function processLevel2(criteria) {
    var criteriaLevel2Id = db.CriteriaLevel2.findOne({ Name: criteria.Name })._id;
    var currentIndex = db.CriteriaLevel3.find({CriteriaLevel2Id: criteriaLevel2Id }).sort({Order:-1}).limit(1)[0].Order;
    criteria.Level3.forEach(function (criteria, index) {
        processLevel3(criteriaLevel2Id, criteria, currentIndex + index + 1);
    });
}

function deleteFromLevel2(criteria){
    var criteriaLevel2Id = db.CriteriaLevel2.findOne({ Name: criteria.Name })._id;
    criteria.Level3.forEach(function (criteria) {
        deleteFromLevel3(criteriaLevel2Id, criteria);
    });
}

function deleteFromLevel3(criteriaLevel2Id, criteria) {
    var criteriaLevel3 = db.CriteriaLevel3.findOne({ Name: criteria.Name, CriteriaLevel2Id: criteriaLevel2Id });
    if(criteriaLevel3 != null)
    {
        var criteriaLevel3Id = criteriaLevel3._id;
        criteria.Level4.forEach(function (criteria) {
            deleteFromLevel4(criteriaLevel2Id, criteriaLevel3Id, criteria);
        });
        db.CriteriaLevel3.deleteOne({_id:criteriaLevel3Id });
    }
}

function deleteFromLevel4(criteriaLevel2Id, criteriaLevel3Id, criteria) {
    var templateCriteria = db.TemplateCriteria.findOne({CriteriaLevel2Id: criteriaLevel2Id, CriteriaLevel3Id: criteriaLevel3Id});
    if(templateCriteria != null)
    {
        var templateCriteriaId = templateCriteria._id;
        db.TemplateCriteria.deleteOne({_id: templateCriteriaId});
        db.FilterCriteria.deleteMany({TemplateCriteriaId:templateCriteriaId });
    }
}

function processLevel3(criteriaLevel2Id, criteria, index) {
    if (!db.CriteriaLevel3.findOne({ Name: criteria.Name, CriteriaLevel2Id: criteriaLevel2Id })) 
    {
        db.CriteriaLevel3.insert({
            _id: NUUID(uuid()),
            Name: criteria.Name,
            ShortName: criteria.Name,
            Order: NumberInt(index),
            CriteriaLevel2Id: criteriaLevel2Id,
            Category: "None"
        });
    }
    var criteriaLevel3Id = db.CriteriaLevel3.findOne({ Name: criteria.Name, CriteriaLevel2Id: criteriaLevel2Id })._id;
    criteria.Level4.forEach(function (criteria) {
        processLevel4(criteriaLevel2Id, criteriaLevel3Id, criteria);
    });
}

function processLevel4(criteriaLevel2Id, criteriaLevel3Id, criteria) {
    if (!db.TemplateCriteria.findOne({ Name: criteria.Name, CriteriaLevel2Id: criteriaLevel2Id })) {
        if(criteria.MaxValue)
        db.TemplateCriteria.insert({
            _id: NUUID(uuid()),
            Name: criteria.Name,
            CriteriaEntity: null,
            CriteriaEntityField: criteria.CriteriaEntityField,
            CriteriaType: NumberInt(criteria.CriteriaType),
            CriteriaLevel2Id: criteriaLevel2Id,
            CriteriaLevel3Id: criteriaLevel3Id,
            IsScreenable: criteria.IsScreenable,
            ResearchProducts: ["CorporateGovernance"],
            GetsValueFromParent: true,
            HasFullRangeChart: false,
            MaxValue: NumberInt(criteria.MaxValue)
       });
        else
        db.TemplateCriteria.insert({
            _id: NUUID(uuid()),
            Name: criteria.Name,
            CriteriaEntity: null,
            CriteriaEntityField: criteria.CriteriaEntityField,
            CriteriaType: NumberInt(criteria.CriteriaType),
            CriteriaLevel2Id: criteriaLevel2Id,
            CriteriaLevel3Id: criteriaLevel3Id,
            IsScreenable: criteria.IsScreenable,
            ResearchProducts: ["CorporateGovernance"],
            GetsValueFromParent: true,
            HasFullRangeChart: false
       });
    }
}

function updateChangedCriteria() {
    db.CriteriaLevel3.updateOne({Name:"CG.6.7 Lobbying & Political Expenses"},{$set:{"Name":"CG.6.7 Lobbying and Political Expenses", "ShortName":"CG.6.7 Lobbying and Political Expenses"}});
    var templateCriteria = db.TemplateCriteria.findOne({ Name: "CG.6.7 Lobbying & Political Expenses-Score"});
    if(templateCriteria != null)
    {
        db.TemplateCriteria.updateOne({_id:templateCriteria._id},{$set:{"Name":"CG.6.7 Lobbying and Political Expenses-Score", "CriteriaEntityField":"CG67 Lobbying and Political Expenses-Score"}});
        db.FilterCriteria.updateMany({TemplateCriteriaId:templateCriteria._id},{$set:{"Name":"CG.6.7 Lobbying and Political Expenses-Score","CriteriaEntityField":"CG67 Lobbying and Political Expenses-Score"}});
    }
}

processLevel2(criteriaToAdd);
deleteFromLevel2(criteriaToDelete);
updateChangedCriteria();